home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993…ch: Other People's Memory / ADC Developer CD (1993-03) (''Other People's Memory'')_iso / Dev.CD Mar 93.iso / Development Platforms / CSMP Digests / csmp-v1-205.txt < prev    next >
Encoding:
Text File  |  1992-11-18  |  54.1 KB  |  1,698 lines  |  [TEXT/MPS ]

  1. C.S.M.P. Digest             Tue, 03 Nov 92       Volume 1 : Issue 205
  2.  
  3. Today's Topics:
  4.  
  5.     Think C Posix library
  6.     Wanted: Code fragment using FindFolder() to get prefs. folder
  7.     MacTCP, ASR's and completion routine hell
  8.     Getting a dialog in front
  9.     MACSBUG Dcmd for "Shut Down"
  10.     Best Debugger for MPW/C++?
  11.     Restart @interrupt time with VN
  12.     Parsing text files
  13.  
  14.  
  15.  
  16. The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
  17.  
  18. The digest is a collection of article threads from the internet newsgroup
  19. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  20. regularly and want an archive of the discussions.  If you don't know what a
  21. newsgroup is, you probably don't have access to it.  Ask your systems
  22. administrator(s) for details.  (This means you can't post questions to the
  23. digest.)
  24.  
  25. Each issue of the digest contains one or more sets of articles (called
  26. threads), with each set corresponding to a 'discussion' of a particular
  27. subject.  The articles are not edited; all articles included in this digest
  28. are in their original posted form (as received by our news server at
  29. cs.uoregon.edu).  Article threads are not added to the digest until the last
  30. article added to the thread is at least one month old (this is to ensure that
  31. the thread is dead before adding it to the digest).  Article threads that
  32. consist of only one message are generally not included in the digest.
  33.  
  34. The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu
  35. [128.223.8.8] in the directory /pub/mac/csmp-digest.  Be sure to read the
  36. file /pub/mac/csmp-digest/README before downloading any files.  The most
  37. recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the
  38. directory /info-mac/digest/csmp.  If you don't have ftp capability, the sumex
  39. archive has a mail server; send a message with the text '$MACarch help' (no
  40. quotes) to LISTSERV@ricevm1.rice.edu for more information.
  41.  
  42. The digest is also available via email.  Just send a note saying that you
  43. want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
  44. automatically receive each new issue as it is created.  Sorry, back issues
  45. are not available through the mailing list.
  46.  
  47. Send administrative mail to mkelly@cs.uoregon.edu.
  48.  
  49.  
  50. -------------------------------------------------------
  51.  
  52. From: tim@maths.tcd.ie (Timothy Murphy)
  53. Subject: Think C Posix library
  54. Organization: Dept. of Maths, Trinity College, Dublin, Ireland.
  55. Date: Fri, 2 Oct 1992 17:09:08 GMT
  56.  
  57.  
  58. I recently ported a number of GNU programs to the Mac --
  59. including perl-4.035, rcs-5.6, diff-2.0 and patch-2.0.12u8 --
  60. using Think C.
  61. To avoid repetition, I wrote a library 
  62. called, rather grandiosely, ThinkCPosix or just Posix.
  63. (I say "wrote", but in fact code for many of the functions
  64. was collected from PD archives.)
  65.  
  66. The following note describes what this library is,
  67. and how it can be obtained and used.
  68.  
  69. ===================== ThinkCPosix.tex ===================== 
  70. \documentstyle[rcs,a4,12pt]{article}
  71.  
  72. % rcs.sty is available from ftp.uni-stuttgart.de
  73. % in the directory soft/tex/latex-style-supported .
  74.  
  75. \RCS$Revision: 1.1 $
  76. \RCS$Date: 1992/09/14 14:28:23 $
  77.  
  78. \catcode`\"=\active
  79. \def"#1"{{\tt #1}}
  80.  
  81. \begin{document}
  82.  
  83. \title{A Posix Library for Think C}
  84.  
  85. \author{Timothy Murphy\\
  86. Trinity College Dublin\\
  87. ("tim@maths.tcd.ie")}
  88.  
  89. \date{\RCSDate\\[2mm]
  90. (Version \RCSRevision)}
  91.  
  92. \maketitle
  93.  
  94. \begin{abstract}
  95. This library is intended to supplement
  96. the ANSI and Unix libraries provided with Think C,
  97. by supplying as many of the missing Posix functions as possible.
  98. The library was developed to assist in porting
  99. GNU programs to the Macintosh\footnotemark.
  100. \end{abstract}
  101.  
  102. \footnotetext{To date the author has ported
  103. the following GNU programs to the Mac:
  104. "diff-1.15",
  105. "patch-2.012u6",
  106. "rcs-5.6",
  107. "bison-1.18",
  108. "flex-2.3.7",
  109. "perl-4.035".}
  110.  
  111. \section{Status}
  112.  
  113. This library is placed in the Public Domain.
  114. It may be used and modified freely---%
  115. though the author would be grateful
  116. for notification of any such modifications,
  117. and would prefer if his name and e-mail address
  118. were left on all files, to this end.
  119.  
  120. \section{Availability}
  121.  
  122. The library is available by anonymous FTP from "ftp.maths.tcd.ie"
  123. in the directory "pub/Mac/ThinkCPosix-1.1".
  124. The compiled library is contained in the file "Posix.hqx".
  125. The source files are archived in "ThinkCPosix.hqx".
  126. This includes the Think C project "Posix.$\pi$".
  127.  
  128. \section{Acknowledgements}
  129.  
  130. The author has used freely code in the archives
  131. pointed out to him,
  132. in particular code by:
  133. Guido van Rossum ("guido@cwi.nl"), and
  134. Mathias Neearcher.
  135. (Where code is taken more or less verbatim,
  136. this is indicated in the relevant files.)
  137.  
  138. He is also grateful for assistance from:
  139. Kenneth Seah ("kseah@procyon.austin.tx.us"),
  140. Sak Wathanasin ("sw@network-analysis-ltd.co.uk"),
  141. John W. Hardin ("hardin@mcc.com"), and
  142. Gary J. Henderson ("gary@iscnvx.lmsc.lockheed.com")
  143.  
  144. \section{Posix}
  145.  
  146. The use of the term ``Posix'' may be misleading---%
  147. it is certainly not meant to imply that the functions satisfy
  148. any Posix standards
  149. (of which the author is largely ignorant).
  150. It is intended simply as a description
  151. of the kind of functions included---%
  152. namely, those Posix functions not included
  153. in the Think C ANSI or Unix libraries.
  154.  
  155. Many of the functions
  156. (in particular those in the file "dummy.c")
  157. do no more than return an appropriate value,
  158. indicating success or failure, as deemed appropriate.
  159.  
  160. \section{Compilation}
  161.  
  162. To re-compile the library,
  163. the included project "Posix.$\pi$" can be used.
  164. Just choose the "Build Library" option
  165. in the "Project" menu.
  166.  
  167. The author has all the ANSI options turned on,
  168. as well as "Require prototypes".
  169. The 4-byte int option and 68020 code option
  170. are turned off.
  171.  
  172. \section{Usage}
  173.  
  174. Any file using the library should
  175. \begin{verbatim}
  176.       #include "ThinkCPosix.h"
  177. \end{verbatim}
  178. The header ("*.h") files should be placed somewhere
  179. in the Think C tree (ie below the Think C application).
  180.  
  181. Whenever the "Posix" library is included,
  182. the Think C "MacTraps" library must also be included.
  183. (This could probably be avoided by abstracting
  184. the very few MacTraps functions called.
  185. But is that legal?)
  186.  
  187. \section{Notes}
  188. These are a few random thoughts on some of the functions
  189. in the library.
  190.  
  191. \begin{description}
  192.  
  193. \item["alloca()"]
  194. This has been included to avoid duplication.
  195. Note that the prototype is "void *alloca(size\_t)",
  196. rather than "char *alloca(unsigned)".
  197.  
  198. \item["dup()"]
  199. The functions "dup()" and "dup2()"
  200. (as implemented here)
  201. both close the original file after duplication.
  202. The reason for this is that Think C adopts the non-standard,
  203. if plausible, policy of including some file-functions
  204. (such as "close")
  205. as part of the file structure.
  206. So a "close(fd)" addressed to the original descriptor
  207. would also close the duplicate.
  208. (This may be a misunderstanding on the author's part.)
  209.  
  210. \item["getpasswd()"]
  211. This (and one or two other functions)
  212. call "getlogin()" in the Think C Unix library
  213. to find the user's name.
  214. This latter must be set---%
  215. under System 7, at least---%
  216. in the "Sharing Setup" Control Panel,
  217. as described in the Macintosh Networking Reference manual.
  218. (I believe that under System 6 the username was changed
  219. on the Chooser panel.)
  220.  
  221. \item["Open()"]
  222. The library includes a few ``substitute'' functions,
  223. eg "Perror()" and "Open()".
  224. The idea is that these can be used in place of
  225. "perror()" or "open()" by including the line
  226. \begin{verbatim}
  227.       #define open Open
  228. \end{verbatim}
  229. (or equivalent) at a judicious point in the program---%
  230. probably at the end of the configuration file,
  231. "conf.h" or whatever.
  232.  
  233. The function "Open(char*, int, ...)"
  234. allows "open()" to take more than 2 arguments
  235. (as seems increasingly the practice),
  236. although these extra arguments are ignored.
  237.  
  238. \item["Perror()"]
  239. This gives a brief description of the error (if it can)
  240. rather than just the number as in "perror()".
  241. The Think C function "strerror()"---%
  242. which the author had not noticed---%
  243. may render this unnecessary.
  244.  
  245. \end{description}
  246.  
  247. \section{Gnu ports}
  248.  
  249. In principle the files 
  250. "patch.hqx", "diff.hqx", "perl.hqx", "ci.hqx", etc,
  251. in the directory "pub/Mac" at "ftp.maths.tcd.ie"
  252. contain the compiled applications.
  253.  
  254. The source for these applications---%
  255. or rather, the diff-files from the standard distributions---%
  256. are in the appropriate subdirectory,
  257. eg "pub/Mac/diff-2.0".
  258.  
  259. Unfortunately, none of these ports are yet documented properly.
  260.  
  261. \section{Development}
  262.  
  263. The author would be very grateful
  264. for any suggested improvements or extensions.
  265. Please send them to "tim@maths.tcd.ie".
  266. Any material used will be duly acknowledged.
  267.  
  268. Implementation of functions related to 
  269. "pipe", "exec" and "spawn"
  270. would be particularly useful.
  271. (The "exec()" function in the Think C Unix library
  272. ignores all arguments except for the application to be launched.
  273. It would be nice if these arguments could be properly passed---%
  274. as must surely be feasible.)
  275.  
  276.  
  277. \end{document}
  278. ===========================================================
  279.  
  280.  
  281. - -- 
  282. Timothy Murphy  
  283. e-mail: tim@maths.tcd.ie
  284. tel: +353-1-2842366
  285. s-mail: School of Mathematics, Trinity College, Dublin 2, Ireland
  286.  
  287. ---------------------------
  288.  
  289. From: zimerman@phoenix.Princeton.EDU (Jacob Ben-david Zimmerman)
  290. Subject: Wanted: Code fragment using FindFolder() to get prefs. folder
  291. Organization: Princeton University
  292. Date: Thu, 1 Oct 1992 15:08:43 GMT
  293.  
  294. Hi all. I'm sorry if this is a FAQ, but I'm having trouble figuring it
  295. out...I was wondering if anyone could provide me with a code fragment
  296. which illustrates how to use FindFolder() to get a VRefNum for the
  297. Preferences folder (and create on if it doesn't exist.)  I am using
  298. THink C 5.0.  In addition, I am more than a bit lost on exactly how to
  299. handle transferring a couple of hundred bytes to and from disk.  For
  300. example, IM talks about passing a buffer to the disk routines.  Is this
  301. a predefined buffer? Is it one I need to create myself?  Does it have to
  302. be of a certain size?  Any help is much appreciated! Thanks for your
  303. time and patience.
  304.  
  305. - -JBZimmerman!
  306. 0.2 of a Mac programmer. :-) And working on it.
  307. - -- 
  308. ___________           |-Is that Scotch over there?  Hold everything.
  309.      ||               |                -Sean Connery, The Russia House
  310. ||   ||acob Zimmerman!+> <zimerman@phoenix.Princeton.EDU> INTERNET 
  311.  \===/                |  <zimerman@PUCC>                  BITNET
  312.  
  313. +++++++++++++++++++++++++++
  314.  
  315. From: oster@well.sf.ca.us (David Phillip Oster)
  316. Organization: Whole Earth 'Lectronic Link
  317. Date: Thu, 1 Oct 1992 16:20:22 GMT
  318.  
  319. This is a fragment from one of my products.:
  320.  
  321. OSErr InitialPreferencesLookUp(){
  322.     Str255    s;
  323.     LongInt    ff;
  324.     OSErr    val;
  325.     Integer prefVRef;
  326.     LongInt    prefDirId;
  327.     SFReply    reply;
  328.  
  329. /* put the name of the preferences file in the reply record.
  330.  */
  331.     GetIndString(reply.fName, kMainStrs, kDefaultS);
  332.     if(noErr == Gestalt(gestaltFindFolderAttr, &ff) && (ff & (1L << gestaltFindFolderPresent))){
  333.         val = FindFolder(kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder,
  334.             &prefVRef, &prefDirId);
  335.  
  336.         if(noErr == val){ val = FSOpenWD(prefVRef, prefDirId, 'ERIC', &reply.vRefNum); }
  337.         if(noErr == val){ val = OpenIt(&reply); }
  338. /* do not close this working directory! */
  339.     }else{
  340. /* initialize the Str255 to "\p:Preferences:" note colons. */
  341.         GetIndString(s, kMainStrs, kPrefDirS);
  342.         Concat(s, reply.fName);        /* pin tail on name */
  343.         StrMove(s, reply.fName);    /* move result back to reply */
  344.         reply.vRefNum = world.sysVRefNum;
  345.         val = OpenIt(&reply);
  346.     }
  347.     return val;
  348. }
  349.  
  350. ---------------------------
  351.  
  352. From: ejohnson@void.ncsa.uiuc.edu (Eric E. Johnson)
  353. Subject: MacTCP, ASR's and completion routine hell
  354. Organization: University of Illinois at Urbana
  355. Date: Thu, 1 Oct 1992 17:01:18 GMT
  356.  
  357. I've been working on a networked, role playing game.  So those who can
  358. help will be helping to alleviate the relative dearth of games on the
  359. Macintosh.
  360.  
  361. The game requires that there be frequent exchanges of data between the
  362. server and client.  The amount of data is small, under 100 bytes, and
  363. I've been referring to the exchanges as the heartbeat.  As an example,
  364. the heartbeat leaves the server, and is sent to the client.  The
  365. client reads it in, processes the client's data, and sends it back to
  366. the server.
  367.  
  368. The idea is to have the rate of exchange as high as possible.  Since
  369. we are using a Unix based server, turn around time for the heartbeat
  370. on the server end is fairly fast.  Our problem has been the Mac end.
  371.  
  372. After some initial work on the game, I realized that using null events
  373. from WaitNextEvent to parcel out time for networking wasn't working
  374. all that well.  Since there can be long delays between WaitNextEvents
  375. due to screen redraws, the networking can be very jittery.  The
  376. intelligent was to use interrupts, which would work during screen
  377. redraws.  
  378.  
  379. MacTCP offers two types of notification routines.  One routine, the
  380. ASR, calls a function that you specify when new data has arrived, when
  381. the connection is closing, or other similar events.  The second
  382. notification routine is a routine that's called upon completion of an
  383. async routine.
  384.  
  385. I tried writing the networking using ASR's alone, and another using
  386. async notification routines alone.  Neither worked very well.  The
  387. heartbeat would be exchanged for a while, but eventually a brutal
  388. crash would ensue.  Unfortunately, the crash was never consistent so
  389. it was difficult to debug.
  390.  
  391. Last night, I decided to rewrite the client end on the Mac to use both
  392. an ASR and an async completion routine.  When the heartbeat arrives,
  393. MacTCP calls my ASR.  In my ASR, I issue an *async* read with a
  394. completion routine pointing to my send routine.  The ASR reads in the
  395. data, and exits fine.  When the async read is done, the completion
  396. routine is called, which then sends back out data.  The heartbeat in
  397. port is different from the heartbeat out port, which would eliminate
  398. any problems MacTCP would have with multiple async commands on the
  399. same port.
  400.  
  401. This works, but comes to screaching halt on the sixteenth beat.  The
  402. server sends out the sixteenth beat, and nothing ever comes back from
  403. the client.  The client has consistently died on the 16th beat.  By
  404. crash, I mean the mouse no longer responds to movements, but oddly
  405. enough, I'm not tossed into MacsBug.
  406.  
  407. Entering MacsBug via a hardware interrupt reveals very little.  'SC6'
  408. claims a6 points to a bad stack frame.  'SC7' has the same report
  409. every time, with the last five entries being the same every time.  One
  410. of the entries is labeled, _UnimplTrap.  UnimplementedTrap?  How bad
  411. is that?
  412.  
  413. I've tried using MacsBug breakpoints to follow my interrupts, rather
  414. than using the Think C debugger.  This is where things get weird.  If
  415. I set an interrupt at my ASR, MacsBug will stop in the ASR when data
  416. arrives.  I always continue since the interrupt supposedly will run 15
  417. more times.  On the second return of the heartbeat from the server,
  418. MacsBug stops in the ASR.  However, when I tell MacsBug to continue
  419. with execution, MacsBug doesn't break into the ASR anymore.  However,
  420. the server does get the heartbeat back.
  421.  
  422. Obvious problems...
  423.  
  424.     Am I preserving A5?  The ASR's do that for you, and I've done
  425. so in my async completion code.
  426.  
  427.     Turned off optimizations in Think C?  Yep.
  428.  
  429.     Got Think C 5.0.3 for the Quadra?  Yep.
  430.  
  431. Does MacsBug not deal to well with interrupts?  Has anyone had any
  432. luck with networking at interrupt level?  Has anyone tried to do
  433. anything similar to this?  Do completed async calls somehow linger
  434. around in MacTCP?  My thinking is that 16 beats is such a nice power
  435. of 2, and on the 16th beat, too many things are lingering around.
  436.  
  437. Any suggestions?
  438.  
  439. Eric Johnson
  440.  
  441.  
  442.  
  443.  
  444.  
  445. +++++++++++++++++++++++++++
  446.  
  447. From: oster@well.sf.ca.us (David Phillip Oster)
  448. Organization: Whole Earth 'Lectronic Link
  449. Date: Fri, 2 Oct 1992 07:34:13 GMT
  450.  
  451. I have done this in a production system. My experience has been that networking
  452. is so slow, because of the potential of retransmits and time outs, that ANY
  453. useful network program must use asynch i/o and completion routines.
  454.  
  455. tips:
  456. 1.) ignore the ASR(). it is very hard to get this to work right.
  457. 2.) ignore the MacTCP high level interfac e. It isn't async so it is a
  458. joke for anything real.
  459. 3.) Use a middle level interface that handles filling out the parameter
  460. block for you. This is pretty trivial to write.  Embed the parameter block
  461. as the first field of a larger structure, similar to the way a WindowPeek
  462. has a GrafPort embedded in the front of it, but most things just look at
  463. the struct on the front.
  464. 4.) in your main application, statically allocate all the data structures
  465. you'll need. Statically allocate an array of queue records (See OSUtils
  466. chap of Inside mac vol 2 for more information on these.)
  467. 5.) Use the global CurrentA5 to inititialize the ioCurrentA5 field of
  468. your extended parameter block.
  469. 6.) Your completion routine should save the value of A5 in a local,
  470. set A5 from  the ioCurrentA5 of the parameter block (passed in register A0
  471. I believe) and restore A5 on exit.  Look in the file <SetUpA4.h> for
  472. inspiration.
  473. 7.) Your completion routine can communicate with your event loop by 
  474. dequeuing queue records from the free list (See suggestion 4) and 
  475. enqueuing them on a pending list. Enqueu() and Dequeue() are guaranteed
  476. safe to call at interrupt time.
  477. 8.) If you need more help, contact me. My consulting rates are $85.00 per
  478. hour.
  479.  
  480. +++++++++++++++++++++++++++
  481.  
  482. From: resnick@cogsci.uiuc.edu (Pete Resnick)
  483. Organization: University of Illinois at Urbana
  484. Date: Fri, 2 Oct 1992 13:57:03 GMT
  485.  
  486. Of MacTCP, oster@well.sf.ca.us (David Phillip Oster) writes:
  487.  
  488. >1.) ignore the ASR(). it is very hard to get this to work right.
  489.  
  490. Complaint: Anyone who ignores the ASR ignores ICMP messages. *Don't*
  491. ignore the ASR; report and act on ICMP destination unreachables. If
  492. you attempt a TCPActiveOpen and get an ICMP destination unreachable,
  493. TCPAbort the open and report to the user instead of doing what most
  494. programs do, which is wait up to a minute for the damn thing to time
  495. out.
  496.  
  497. >7.) Your completion routine can communicate with your event loop by 
  498. >dequeuing queue records from the free list (See suggestion 4) and 
  499. >enqueuing them on a pending list. Enqueu() and Dequeue() are guaranteed
  500. >safe to call at interrupt time.
  501.  
  502. I like this one; very slick way of doing it. Thanks David. However, it
  503. doesn't solve the reponse time problem that Eric was having, i.e.
  504. having to wait for the WNE to complete. Anyone have any slick
  505. strategies for that?
  506.  
  507. pr
  508. - -- 
  509. Pete Resnick             (...so what is a mojo, and why would one be rising?)
  510. Graduate assistant - Philosophy Department, Gregory Hall, UIUC
  511. System manager - Cognitive Science Group, Beckman Institute, UIUC
  512. Internet: resnick@cogsci.uiuc.edu
  513.  
  514. +++++++++++++++++++++++++++
  515.  
  516. From: mandel@tmc.tulane.edu (Jeff E Mandel)
  517. Date: 2 Oct 92 15:16:35 GMT
  518. Organization: Tulane University School of Medicine
  519.  
  520. In article <BvHyr4.J8D@news.cso.uiuc.edu> Pete Resnick,
  521. resnick@cogsci.uiuc.edu writes:
  522. >>7.) Your completion routine can communicate with your event loop by 
  523. >>dequeuing queue records from the free list (See suggestion 4) and 
  524. >>enqueuing them on a pending list. Enqueu() and Dequeue() are guaranteed
  525. >>safe to call at interrupt time.
  526. >
  527. >I like this one; very slick way of doing it. Thanks David. However, it
  528. >doesn't solve the reponse time problem that Eric was having, i.e.
  529. >having to wait for the WNE to complete. Anyone have any slick
  530. >strategies for that?
  531.  
  532. The "private event queue" approach is the best way I ever found to
  533. communicate between interrupt routines and "safe time". The advantage is
  534. that you can dequeue from your private event queue in a MenuHook or
  535. DragHook. It is also possible to break up your screen refresh into
  536. smaller segments and call the dequeue routine in the loop. Probably, you
  537. are drawing to a gWorld, then copying the gWorld to the screen; just
  538. divide the grafPort into an arbitray number of rects as wide as the
  539. screen, and copy each one of these to the screen, calling your dequeue
  540. routine each time. This will degrade screen performance a bit, but one
  541. way or another, you have to interleave your IO calls into the screen
  542. drawing, so doing it explicitly gives you more control over it. Besides,
  543. it will give your game that vertical wipe effect so popular in video
  544. arcade games :-).
  545.  
  546. There is another way to do what Eric wants, as he really only needs to be
  547. able to queue another IO call, and can preallocate enough parameter
  548. blocks to suffice. The solution I employed in a different problem (but
  549. conceptually similar) was to have a very short completion routine which
  550. queued a deferred task, which did the processing. The deferred task fires
  551. "soon", but there is no guarantee that it will fire before the next
  552. interrupt, or not be interrupted itself, so you need some sort of guard
  553. structures; a spin lock or a semaphore or such, so you don't get confused
  554. about what has and hasn't been done. Why go to the trouble? The deferred
  555. task doesn't block other interrupts, so the mouse doesn't get that jumpy
  556. look (which you can tolerate while initializing a disk, but would drive
  557. your game players crazy).
  558.  
  559. Hope this helps,
  560.  
  561. Jeff E Mandel MD MS
  562. Associate Professor of Anesthesiology
  563. Tulane University School of Medicine
  564. New Orleans, LA
  565.  
  566. mandel@vax.anes.tulane.edu
  567.  
  568. ---------------------------
  569.  
  570. From: karlberg@e.kth.se (KRILLE_KROKODIL)
  571. Subject: Getting a dialog in front
  572. Date: 1 Oct 92 23:32:07 GMT
  573. Organization: KTH, Royal Institute of Technology, School of Electrical Engineering
  574.  
  575. When I start a program I've written in Think Pascal it's supposed to
  576. show a dialog before it enters the main loop. The wierd thing is that 
  577. although I pass behind=POINTER(-1) when I call GetNewDialog it gets 
  578. drawn behind all the other windows on the screen, as does the main 
  579. window until I enter the main loop. Why is that and how do I get round
  580. it?
  581.  
  582.  
  583. Martin
  584.  
  585. - -------------------------------------------------------------------------------
  586.                                     If you have a living frog for breakfast,   
  587.                                     nothing worse can happen during the day.  
  588.  
  589. +++++++++++++++++++++++++++
  590.  
  591. From: absurd@applelink.apple.com (Tim Dierks, software saboteur)
  592. Date: 2 Oct 92 18:56:03 GMT
  593. Organization: MacDTS Marauders
  594.  
  595. In article <00961772.8D5273A0@e.kth.se>, karlberg@e.kth.se
  596. (KRILLE_KROKODIL) wrote:
  597. > When I start a program I've written in Think Pascal it's supposed to
  598. > show a dialog before it enters the main loop. The wierd thing is that 
  599. > although I pass behind=POINTER(-1) when I call GetNewDialog it gets 
  600. > drawn behind all the other windows on the screen, as does the main 
  601. > window until I enter the main loop. Why is that and how do I get round
  602. > it?
  603. > Martin
  604.  
  605. MultiFinder, and System 7, for resons unknown to me, don't bring an
  606. application to the foreground until its event loop starts up; you
  607. can force it to bring you forward by making a few event calls; the
  608. canonical sequence is to call EventAvail() three times; you'll
  609. then be brought to the front.
  610.  
  611. Tim Dierks
  612. MacDTS, but I squeak with glee
  613.  
  614. ---------------------------
  615.  
  616. From: Joel Sumner <js17@cornell.edu>
  617. Subject: MACSBUG Dcmd for "Shut Down"
  618. Organization: Trapped at Cornell University
  619. Date: Mon, 28 Sep 1992 20:19:54 GMT
  620.  
  621. Has anyone written a "Shut Down" or "Power Off" DCMD for MacsBug?  I have
  622. powerbook 100 and the ONLY way to shut off the power is from the Finder 
  623. ShutDown command (there is this thing about not having a power switch or
  624. a power cord to unplug that causes problems... <grin>).  Occasionally,
  625. when I crash the thing, I  don't want to wait for it to do a full re-boot
  626. just to select "Shut Down".  Has anyone written a Macs Bug DCMD (or any
  627. other method from MacsBug) which will do the same thing?  Not even a full
  628. OS shutdown, just a "Power Off" would be nice....
  629.  
  630. - -Joel
  631. Joel Sumner
  632. js17@cornell.edu
  633. q4kx@cornella (Bitnet)
  634. - -----------------------------------------------------------
  635. .sig under construction (like the rest of Cornell)
  636.  
  637. +++++++++++++++++++++++++++
  638.  
  639. From: howes@cat15.cs.wisc.edu (Glenn Howes)
  640. Date: 28 Sep 92 22:22:20 GMT
  641. Organization: University of Wisconsin, Madison -- Computer Sciences Dept.
  642.  
  643. In article <1992Sep28.201954.20830@mail.cornell.edu> Joel Sumner <js17@cornell.edu> writes:
  644. >Has anyone written a "Shut Down" or "Power Off" DCMD for MacsBug?  I have
  645. >a 
  646. >powerbook 100 and the ONLY way to shut off the power is from the Finder 
  647. >ShutDown command (there is this thing about not having a power switch or
  648. >a power cord to unplug that causes problems... <grin>).  Occasionally,
  649. >when I crash the thing, I  don't want to wait for it to do a full re-boot
  650. >just to select "Shut Down".  Has anyone written a Macs Bug DCMD (or any
  651. >other method from MacsBug) which will do the same thing?  Not even a full
  652. >OS shutdown, just a "Power Off" would be nice....
  653.  
  654. It appears to me that pressing both the interupt and the reset buttons and
  655. holding them simultaneously causes a shutdown. Can anybody confirm that
  656. this will also cause the heads to park?
  657.  
  658.  
  659.  
  660. - -- 
  661. - ------------------------------------------------------------------
  662. Glenn R. Howes              Internet: howes@bert.chem.wisc.edu
  663. author: Kermit Tool GH      // Picard & Riker in '92 
  664. - ------------------------------------------------------------------
  665.  
  666. +++++++++++++++++++++++++++
  667.  
  668. From: crod@cc.curtin.edu.au (Scott Kevill)
  669. Organization: Curtin University of Technology
  670. Date: Fri, 2 Oct 1992 01:40:06 GMT
  671.  
  672.  
  673. Hi Joel,
  674.  
  675. If you didn't have a DCMD, you could always use the trap call
  676. (like the ExitToShell used in the old days of ROM mini-debuggers)
  677. as I do.
  678.  
  679. At the debugger prompt, type :
  680. SM 0 3F3C 0 1 A895
  681. G 0
  682.  
  683. or with MacsBug, you can do this in one line :
  684. SM 0 3F3C 0 1 A895;G 0
  685.  
  686. After using this plenty of times for a quick shutdown, especially
  687. on floppy systems, it is fairly quick to type and has the advantage
  688. of working on any debugger.
  689.  
  690. Hope this helps !
  691.  
  692. Scott
  693.  
  694. +-----------------------+--------------------------------------+
  695. I Scott Kevill          I   "Be like me, be original"          I
  696. I crod@cc.curtin.edu.au I                              -- Me   I
  697. +-----------------------+--------------------------------------+
  698. In article <1992Sep28.201954.20830@mail.cornell.edu>, js17@cornell.edu (Joel Sumner) writes:
  699. > Has anyone written a "Shut Down" or "Power Off" DCMD for MacsBug?  I have
  700. > a 
  701. > powerbook 100 and the ONLY way to shut off the power is from the Finder 
  702. > ShutDown command (there is this thing about not having a power switch or
  703. > a power cord to unplug that causes problems... <grin>).  Occasionally,
  704. > when I crash the thing, I  don't want to wait for it to do a full re-boot
  705. > just to select "Shut Down".  Has anyone written a Macs Bug DCMD (or any
  706. > other method from MacsBug) which will do the same thing?  Not even a full
  707. > OS shutdown, just a "Power Off" would be nice....
  708. > -Joel
  709. > Joel Sumner
  710. > js17@cornell.edu
  711. > q4kx@cornella (Bitnet)
  712. > -----------------------------------------------------------
  713. > .sig under construction (like the rest of Cornell)
  714.  
  715. +++++++++++++++++++++++++++
  716.  
  717. From: rjc@monet.ccs.itd.umich.edu (Robert John Churchill)
  718. Organization: University of Michigan
  719. Date: Fri, 2 Oct 1992 13:17:02 GMT
  720.  
  721. In article <1992Oct2.104006.1@cc.curtin.edu.au>, crod@cc.curtin.edu.au
  722. (Scott Kevill) wrote:
  723.  
  724. > If you didn't have a DCMD, you could always use the trap call
  725. > (like the ExitToShell used in the old days of ROM mini-debuggers)
  726. > as I do.
  727.  
  728. > In article <1992Sep28.201954.20830@mail.cornell.edu>, js17@cornell.edu (Joel Sumner) writes:
  729. > > Has anyone written a "Shut Down" or "Power Off" DCMD for MacsBug?
  730.  
  731. Go into Macsbug and type  "G Power"   :)
  732.  
  733. ---------------------------
  734.  
  735. From: D_Gladstone@cs.aukuni.ac.nz (David Gladstone)
  736. Subject: Best Debugger for MPW/C++?
  737. Date: 28 Sep 92 23:39:06 GMT
  738. Organization: Computer Science Dept., Auckland University.
  739.  
  740. I am soon to be embarking on a project that will require the use of C++.
  741. Currently we have MPW C++ v3.1 and Zortech C++ v2.1 for MPW.  The question
  742. I have is about debuggers.  From what I've read in the August APDA
  743. catalogue, there are two options:
  744.  
  745. SADE 1.3.2 : Good scripting, but does not appear to have support for class
  746.              browsing etc.
  747.  
  748. SOURCEBUG v1.0.1 : "Special support for debugging MacApp and object
  749.                    oriented code."
  750.  
  751.                    "A browser interface to display the classes and methods
  752.                       of MacApp or an object oriented program."
  753.  
  754. How do these products fare?  Is the class browser in SourceBug better,
  755. worse, or on par with Think Pascal's (with which I am familiar)?
  756.  
  757. Are there any alternative products on the market which are better?
  758.  
  759. If SADE and SOURCEBUG are the only viable products, which should I buy?
  760. Or 
  761. should I buy both?
  762.  
  763. Either post or email your recommendations.
  764.  
  765. Thank you.
  766.  
  767. D_Gladstone@cs.aukuni.ac.nz   // Dept of Computer Science, // In real life
  768. =============================// University of Auckland,   // as opposed to
  769. Ph: (64) (9) 373-7599 x5336 // Private Bag 92019,        // in a computer:
  770. Fax:(64) (9) 373-7453      // Auckland, New Zealand.    // David Gladstone
  771.  
  772. +++++++++++++++++++++++++++
  773.  
  774. From: Bruce.Hoult@bbs.actrix.gen.nz
  775. Date: Fri, 2 Oct 1992 02:28:49 GMT
  776. Organization: Actrix Information Exchange
  777.  
  778. In article <1992Sep28.233906.26728@cs.aukuni.ac.nz> David Gladstone <D_Gladstone@cs.aukuni.ac.nz> writes:
  779. > I am soon to be embarking on a project that will require the use of C++.
  780. > Currently we have MPW C++ v3.1 and Zortech C++ v2.1 for MPW.  The question
  781. > I have is about debuggers.  From what I've read in the August APDA
  782. > catalogue, there are two options:
  783. > SADE 1.3.2 : Good scripting, but does not appear to have support for class
  784. >              browsing etc.
  785. > SOURCEBUG v1.0.1 : "Special support for debugging MacApp and object
  786. >                    oriented code."
  787. >                    "A browser interface to display the classes and methods
  788. >                       of MacApp or an object oriented program."
  789.  
  790.  
  791. I use both daily.  I wouldn't want to be without either, although if I
  792. had to choose only one I think, uuuuuuhhhh, when you need SADE you
  793. *need* it.
  794.  
  795. SourceBug is better for general noodling around.  It's marginally
  796. better for tracing control-flow type problems.  It's much better than
  797. SADE for checking the match between source code and machine code -- you
  798. can display two windows of the same function, one in source the other
  799. in ASM and you can set breakpoints or singlestep in either view at
  800. will.  You can have continuously updated windows containing the values
  801. in registers *and* in high-level program variables at the same time.
  802. It's easier to drop down into MACSBUG and come back again than in SADE
  803. (actually I 've never figured out how to do that in SADE...).
  804. SourceBug is immeasurably better than SADE at tracing around the data
  805. of PascalObjects -- you can click on the name of a class and a list of
  806. all currently instantiated objects of that class appears.  Clicking on
  807. an object shows the fields of that object.
  808.  
  809.  
  810. Like MPW itself, SADE is programmable.  That means SADE vs SourceBug
  811. is a bit like MPW vs THINK.  SADE has less built in than SourceBug,
  812. but you can probably add everything I listed in the previous paragraph
  813. to it if you take the time to write the necesary scripts.  I use SADE
  814. less than SourceBug, but when I do use it it's for its repeatability,
  815. its non-object data examining ability or its memory-stomper catching.
  816.  
  817. Ever have a bug that only shows up after you go through two dozen
  818. steps, then crashes the Mac?  Get sick of manually steering your
  819. program through those steps time after time?  With SADE you can write
  820. a little script that starts your program and runs it to a breakpoint,
  821. changes the values of a couple of variables or sets the PC to a
  822. different line (to simulate the effects of getting an event from the
  823. user, or otherwise guide the program), runs to another breakpoint etc
  824. etc until you get to the problem situation.  OK, that takes a while to
  825. set up (especially with a certain misfeature added in SADE 1.3 (?)
  826. that makes you chain actions wiht onEntry actions instead of using a
  827. straight line script), but sometimes the alternatives are worse.
  828.  
  829. SADE is also good for examining data that the .SYM file doesn't
  830. properly describe.  My main example of that is a pseudo-template type
  831. (done using macros) I use extensively that stores a dynamic array of
  832. xxxx's in a handle.  SourceBug just shows the whole array as a handle,
  833. but SADE can be convinced to show it as an array of xxxx's.
  834.  
  835. The latest SADE (but you need ETO to get it) has the ability to use the MMU
  836. to protect areas of memory to catch memory stomping bugs.  This can save
  837. lots of aggro sometimes.
  838.  
  839.  
  840. If you've got MPW and  C++ (and therefore C) and are getting SADE and
  841. SourceBug you should probably consider getting the full ETO package instead.
  842. It's a tad expensive but it's pretty good.
  843.  
  844. - -- Bruce
  845. - -- 
  846. Bruce.Hoult@bbs.actrix.gen.nz   Twisted pair: +64 4 477 2116
  847. BIX: brucehoult                 Last Resort:  PO Box 4145 Wellington, NZ
  848. "Cray's producing a 500 MIPS personal computer with 256MB RAM and 8 GB
  849. hard disk that fits in your pocket!"   "Great!  Is it PC compatible?"
  850.  
  851. ---------------------------
  852.  
  853. From: stud08@cc4.kuleuven.ac.be (Karl Pottie)
  854. Subject: Restart @interrupt time with VN
  855. Date: 28 Sep 92 12:52:19 GMT
  856. Organization: K.U.Leuven - Academic Computing Center
  857.  
  858. Hi,
  859.  
  860. I'm writing an init which reboots the mac after a system error. For this
  861. purpose, I call the toolbox routine Restart() at interrupt time. This
  862. works fine except when VM is running. When VM is running the mac simply
  863. blanks its screen and locks up. I tried using DeferUserFN(), but it didn't
  864. help.
  865.  
  866. How do I reboot (restart) a macintosh at interrupt time ? Any quick
  867. and dirty methods ? Any clean method ?
  868.  
  869. Please respond to me directly
  870.  
  871. Karl
  872.  
  873. +++++++++++++++++++++++++++
  874.  
  875. From: jpugh@apple.com (Jon Pugh)
  876. Date: 30 Sep 92 03:38:17 GMT
  877. Organization: Apple Computer, Inc.
  878.  
  879. In article <1992Sep28.125124@cc4.kuleuven.ac.be>, stud08@cc4.kuleuven.ac.be
  880. (Karl Pottie) wrote:
  881. > Hi,
  882. > I'm writing an init which reboots the mac after a system error. For this
  883. > purpose, I call the toolbox routine Restart() at interrupt time. This
  884. > works fine except when VM is running. When VM is running the mac simply
  885. > blanks its screen and locks up. I tried using DeferUserFN(), but it didn't
  886. > help.
  887. > How do I reboot (restart) a macintosh at interrupt time ? Any quick
  888. > and dirty methods ? Any clean method ?
  889.  
  890. We spent a good half an hour laughing about this one in DTS today.  It even
  891. got posted to the unofficial "Wall of Shame".
  892.  
  893. I think Baumwell's suggestion was best.  Stuff the MrBusError number into
  894. the bus error exception vector, then execute that same bus error number. 
  895. That way you get a double exception and the machine reboots.
  896.  
  897. Jon
  898.  
  899. ---------------------------
  900.  
  901. From: u2005681@ucsvc.ucs.unimelb.edu.au
  902. Subject: Parsing text files
  903. Date: 30 Sep 92 04:03:35 GMT
  904. Organization: The University of Melbourne
  905.  
  906. Hi folks,
  907.  
  908. I wonder if any of you people out there can give me some advice?
  909. I've been programming for quite a while but I havn't had much to do
  910. with the Mac file system and related toolbox calls.
  911.  
  912. As part of a new application, I am trying to read a text file of numbers
  913. and strings into a series of variables. The idea is to use the numbers as
  914. co-efficients for a simulation and the strings as labels for various graphs.
  915.  
  916. As I understand it, the Mac OS deals with text files as UNIX-C does with
  917. binary files ie you specify how many bytes to read and what buffer to read
  918. them into. But in the absence of a standard library, how is it possible to 
  919. read numbers and strings of differing lengths?
  920.  
  921. An explanation (or even some source code in C) would be most excellent.
  922.  
  923. I appreciate your time and effort.
  924. C.Hofflin
  925. - ----------------------------------------------
  926. "Insert your own clever, deep and meaningful quote here"
  927.  
  928. +++++++++++++++++++++++++++
  929.  
  930. From: kdlee@milli.cs.umn.edu (Kevin D. Lee)
  931. Organization: University of Minnesota, Minneapolis, CSci dept.
  932. Date: Wed, 30 Sep 1992 14:46:24 GMT
  933.  
  934. In article <1992Sep30.140336.3663@ucsvc.ucs.unimelb.edu.au> u2005681@ucsvc.ucs.unimelb.edu.au writes:
  935. >Hi folks,
  936. >
  937. >I wonder if any of you people out there can give me some advice?
  938. >I've been programming for quite a while but I havn't had much to do
  939. >with the Mac file system and related toolbox calls.
  940. >
  941. >As part of a new application, I am trying to read a text file of numbers
  942. >and strings into a series of variables. The idea is to use the numbers as
  943. >co-efficients for a simulation and the strings as labels for various graphs.
  944. >
  945. >As I understand it, the Mac OS deals with text files as UNIX-C does with
  946. >binary files ie you specify how many bytes to read and what buffer to read
  947. >them into. But in the absence of a standard library, how is it possible to 
  948. >read numbers and strings of differing lengths?
  949. >
  950. >An explanation (or even some source code in C) would be most excellent.
  951. >
  952. >I appreciate your time and effort.
  953. >C.Hofflin
  954. >----------------------------------------------
  955. >"Insert your own clever, deep and meaningful quote here"
  956.  
  957. I handle parsing a text file by reading all of the data into a handle.
  958.  
  959.  
  960. My next step is to lock the handle and start to dereference it by assigning
  961. a char pointer to point to the first byte. I then use the sscanf function 
  962. from ansi c to parse out the items that I am interested in.  After each
  963. sscanf make sure you move your char pointer to the correct position.  If
  964. this is to vague let me know and I will provide more details.
  965.  
  966. Kevin Lee
  967.  
  968.  
  969.  
  970. +++++++++++++++++++++++++++
  971.  
  972. From: bpb9204@tamsun.tamu.edu (Brent)
  973. Organization: Texas A&M Univ., Inc.
  974. Date: Wed, 30 Sep 1992 14:50:12 GMT
  975.  
  976. u2005681@ucsvc.ucs.unimelb.edu.au writes:
  977. |
  978. |As part of a new application, I am trying to read a text file of numbers
  979. |and strings into a series of variables. The idea is to use the numbers as
  980. |co-efficients for a simulation and the strings as labels for various graphs.
  981.  
  982. |As I understand it, the Mac OS deals with text files as UNIX-C does with
  983. |binary files ie you specify how many bytes to read and what buffer to read
  984. |them into. But in the absence of a standard library, how is it possible to 
  985. |read numbers and strings of differing lengths?
  986.  
  987. What do you mean, "absence of a standard library?"  What are you using?
  988.  
  989. |An explanation (or even some source code in C) would be most excellent.
  990.  
  991. I don't know the format of what you want to read in, so you'll have to
  992. massage the following into your own form.
  993.  
  994. The idea is to use your own buffering.  You do this by either using an
  995. array or allocating (with NewPtr() or NewHandle() ) an appropriately-sized
  996. buffer.  The size of the buffer is important - if you make it a multiple
  997. of the disk block size, your reads will be much faster.  A good buffer
  998. size is 1024 or 2048 bytes.  (Is a mac disk block 512 bytes? or 1024?)
  999.  
  1000. What you'll do is pass bits of your buffer to string conversion utilities
  1001. like Str2Num.  This will convert the string representation of a number
  1002. into an Extended type.  When you are reading a string, just copy characters
  1003. from the buffer to your string array directly.  
  1004.   Note: Str2Num takes a "DecStr" type, which is effectively an array
  1005.   of 255 characters.  That's how long your number representation can be.  
  1006.  
  1007. When your buffer position is equal to the length of the buffer, it's time
  1008. to read in another block of data.
  1009.  
  1010. This idea isn't difficult to implement and can be easily done in an
  1011. afternoon, for sure.  Some C books mention buffering, if you need a reference.
  1012.  
  1013. I decided to go ahead and write some simple stuff.  Here is my 10 minute
  1014. hack:
  1015. - -------  pseudo-C follows
  1016.  
  1017. char buffer[1024];
  1018. int bufpos;
  1019. int endoffile=0;
  1020.  
  1021. LoadBuffer()
  1022. {
  1023.    OSErr err;
  1024.    long count = 1024;
  1025.  
  1026. /* inputRefNum is reference number of a pre-opened input file **/
  1027.    err = FSRead( inputRefNum, &count, buffer);  /* check error result */
  1028.    if (count == 0)
  1029.      endoffile = 1;
  1030.    bufpos = 0;
  1031. }
  1032.  
  1033. ScanNumber(Extended *e, )
  1034. {
  1035.    *e = Str2Num( &buffer[bufpos]);
  1036.    /*** update buffer position ***/
  1037.    while( buffer[bufpos] is in {0-9eE+-} )
  1038.      bufpos++;
  1039.  
  1040. /* Note:  this routine does not take into account the situation like:
  1041.    early data in file...... 10.23e49  ....... later data in file
  1042.    buffer read n ---------------||----------- buffer read n+1 ...
  1043. */
  1044. }
  1045.  
  1046. ScanString( char *s, int maxlen)
  1047. {
  1048.    while (maxlen--)
  1049.    {
  1050.      if (bufpos == 1024)  LoadBuffer();
  1051.      *s++ = buffer[bufpos++];
  1052.      if (buffer[bufpos] is some character that does not belong in a string)
  1053.        return;
  1054.    }
  1055. }
  1056.  
  1057. ParseFile()
  1058. {
  1059.   while (!endoffile)
  1060.   {
  1061.     /* this will be a series of calls to ScanNumber() and ScanString()
  1062.     ** that you'll have to figger out.
  1063.     */
  1064.   }
  1065. }
  1066. - -- 
  1067. - ------------------------------------------------------------------------------
  1068. Brent P. Burton, N5VMG                          Department of Computer Science
  1069. bpb9204@tamsun.tamu.edu                                   Texas A&M University
  1070.       What are typical family values?      Good buys at WalMart.
  1071.  
  1072. +++++++++++++++++++++++++++
  1073.  
  1074. From: Michael Hecht <Michael_Hecht@mac.sas.com>
  1075. Date: Wed, 30 Sep 1992 16:47:29 GMT
  1076. Organization: SAS Institute Inc.
  1077.  
  1078. In article <1992Sep30.140336.3663@ucsvc.ucs.unimelb.edu.au> ,
  1079. u2005681@ucsvc.ucs.unimelb.edu.au writes:
  1080. >As part of a new application, I am trying to read a text file of 
  1081. >numbers and strings into a series of variables. The idea is to use the 
  1082. >numbers as co-efficients for a simulation and the strings as labels for 
  1083. >various graphs.
  1084.  
  1085. I've written a routine that imports a tab-delimited text file in which
  1086. the first record contains column names. You supply it with an FSSpec for
  1087. the text file, a STR# id containing the column names you're looking for,
  1088. and an action proc to be called for each row. It reads the data and for
  1089. each row builds a string list of column values in the order you specified
  1090. by the STR#. It then passes this info to the row action proc.
  1091.  
  1092. I wrote it to use the Task Manager, so all the I/O could be async and
  1093. reading/processing could take place in the background. This part could be
  1094. easily removed, or replaced with Threads, however.
  1095.  
  1096. If you're interested, let me know and I'll post it.
  1097.  
  1098. - --Michael
  1099.  
  1100. =======================================================================
  1101. Michael P. Hecht                 | Internet:  Michael_Hecht@mac.sas.com
  1102. SAS Institute Inc.; Cary, NC USA | AppleLink: SAS.HECHT
  1103.  
  1104. +++++++++++++++++++++++++++
  1105.  
  1106. From: beard@toadflax.UCDavis.EDU (Patrick C. Beard)
  1107. Date: 30 Sep 92 19:40:29 GMT
  1108. Organization: UC Davis, EECS Division of Computer Science
  1109.  
  1110. In article <1992Sep30.140336.3663@ucsvc.ucs.unimelb.edu.au>,
  1111. u2005681@ucsvc.ucs.unimelb.edu.au writes:
  1112. > Hi folks,
  1113. > I wonder if any of you people out there can give me some advice?
  1114. > I've been programming for quite a while but I havn't had much to do
  1115. > with the Mac file system and related toolbox calls.
  1116. > As part of a new application, I am trying to read a text file of numbers
  1117. > and strings into a series of variables. The idea is to use the numbers as
  1118. > co-efficients for a simulation and the strings as labels for various graphs.
  1119. > As I understand it, the Mac OS deals with text files as UNIX-C does with
  1120. > binary files ie you specify how many bytes to read and what buffer to read
  1121. > them into. But in the absence of a standard library, how is it possible to 
  1122. > read numbers and strings of differing lengths?
  1123.  
  1124. If you are programming in THINK C, use the ANSI library and save
  1125. yourself a lot of work.
  1126. With this library, you can open up files with fopen("filename", "r") and
  1127. use fgets or fscanf
  1128. to parse your input. Here's a fragment. Say your file has some numbers,
  1129. all floats:
  1130.  
  1131. 1.23 0.345 100.2
  1132. [as many lines of this form as you like]
  1133.  
  1134. A small program to read this would be:
  1135.  
  1136. main()
  1137. {
  1138.   float a, b, c; // numbers we'll be reading in.
  1139.   FILE* f;       // stdio file pointer.
  1140.  
  1141.   f = fopen("file", "r"); // open the file for reading.
  1142.   while (fscanf(f, "%f %f %f", &a, &b, &c) != EOF) { // read the numbers.
  1143.     printf("a = %f, b = %f, c = %f\n", a, b, c);
  1144.   }
  1145.   fclose(f);
  1146. }
  1147.  
  1148. Reading strings is a matter of using %s rather than %f, unless of course
  1149. your strings
  1150. have embedded white space, which makes it more complicated. This should
  1151. get you started.
  1152.  
  1153. Good luck!
  1154.  
  1155. // Patrick C. Beard
  1156. // Department of Computer Science, U. C. Davis
  1157. // pcbeard@ucdavis.edu
  1158.  
  1159. +++++++++++++++++++++++++++
  1160.  
  1161. From: Michael Hecht <Michael_Hecht@mac.sas.com>
  1162. Date: Fri, 2 Oct 1992 13:46:55 GMT
  1163. Organization: SAS Institute Inc.
  1164.  
  1165. In article <1992Sep30.140336.3663@ucsvc.ucs.unimelb.edu.au> ,
  1166. u2005681@ucsvc.ucs.unimelb.edu.au writes:
  1167. >An explanation (or even some source code in C) would be most excellent.
  1168.  
  1169. In article <BvEHB5.JL4@unx.sas.com> Michael Hecht,
  1170. Michael_Hecht@mac.sas.com writes:
  1171. >If you're interested, let me know and I'll post it.
  1172.  
  1173. Well, I guess five requests warrants my sending this source code around
  1174. the world. :-)
  1175.  
  1176. Import uses Task Manager 2.3, which includes AtTaskExit/TaskExit support.
  1177. If you don't have this version, you need to get it. Or, you could change
  1178. the TASK #define to 0.
  1179.  
  1180. Use it in good health!
  1181. - --Michael
  1182.  
  1183. =======================================================================
  1184. Michael P. Hecht                 | Internet:  Michael_Hecht@mac.sas.com
  1185. SAS Institute Inc.; Cary, NC USA | AppleLink: SAS.HECHT
  1186.  
  1187. =======================================================================
  1188.  
  1189. // /* Add these to the appropriate header file */
  1190. // typedef struct {
  1191. //    short            numStrings;
  1192. //    Str255            string;
  1193. // } **StringListHandle;
  1194. // 
  1195. // typedef OSErr ( *RowActionProc )( StringListHandle rowData,
  1196. //                             long refCon );
  1197. //
  1198. // OSErr Import( FSSpecPtr file, short columnListID,
  1199. //                RowActionProc rowAction, long refCon );
  1200.  
  1201.  
  1202. /*
  1203.  *    Import() will read a tab-delimited text file given a file spec, 
  1204.  *    a list of column names to look for (via a STR# id), and an action 
  1205.  *    proc w/refCon to be executed for each row.
  1206.  *
  1207.  *    The column label string list should probably be purgeable.
  1208.  *
  1209.  *    This function is designed to be called from a task. If you don't 
  1210.  *    want to call this from a task, change the TASK #define to 0.
  1211.  *
  1212.  *    Michael Hecht (Michael_Hecht@mac.sas.com)
  1213.  *    1-oct-1992
  1214.  */
  1215.  
  1216.  
  1217. /* Change this to 0 if you're not using Task Manager 2.3 */
  1218. #define TASK        1
  1219.  
  1220.  
  1221. #if TASK
  1222. #include "Task.h"
  1223. #else
  1224. #define TaskYield()
  1225. #endif
  1226.  
  1227.  
  1228. /* Size of our import buffer */
  1229. #define kImportBufferSize        1024
  1230.  
  1231. /* Context information needed for import */
  1232. typedef struct {
  1233.     HParmBlkPtr            pb;
  1234.     long                bufIndex;
  1235.     Boolean                endOfFile;
  1236.     short                **columnMap;
  1237.     short                nReqColumns;
  1238.     StringListHandle    rowData;
  1239. } ImportRecord, **ImportHandle;
  1240.  
  1241.  
  1242. /* Import task exit routine. It cleans up all our storage, etc. */
  1243. static void ImportExit( ImportHandle ctx )
  1244. {
  1245.     if(( *ctx )->rowData )
  1246.         DisposHandle(( Handle )( *ctx )->rowData );
  1247.  
  1248.     if(( *ctx )->columnMap )
  1249.         DisposHandle(( Handle )( *ctx )->columnMap );
  1250.  
  1251.     if(( *ctx )->pb ) {
  1252.         Ptr            buffer;
  1253.  
  1254.  
  1255.         buffer = ( *ctx )->pb->ioParam.ioBuffer;
  1256.         if( buffer )
  1257.             DisposPtr( buffer );
  1258.  
  1259.         if(( *ctx )->pb->ioParam.ioRefNum )
  1260.             PBCloseSync(( ParmBlkPtr )(( *ctx )->pb ));
  1261.  
  1262.         DisposPtr(( Ptr )( *ctx )->pb );
  1263.     }
  1264.  
  1265.     DisposHandle(( Handle )ctx );
  1266. }
  1267.  
  1268. static OSErr TOpen( HParmBlkPtr pb )
  1269. {
  1270.     OSErr                err;
  1271.  
  1272.  
  1273.     pb->ioParam.ioCompletion = 0;
  1274.  
  1275.     err = PBHOpenDFAsync( pb );
  1276.     if( err != noErr )
  1277.         return err;
  1278.  
  1279.     while( pb->ioParam.ioResult > 0 )
  1280.         TaskYield();
  1281.  
  1282.     return pb->ioParam.ioResult;
  1283. }
  1284.  
  1285. static OSErr TRead( HParmBlkPtr pb )
  1286. {
  1287.     OSErr                err;
  1288.  
  1289.  
  1290.     pb->ioParam.ioCompletion = 0;
  1291.  
  1292.     err = PBReadAsync(( ParmBlkPtr )pb );
  1293.     if( err != noErr )
  1294.         return err;
  1295.  
  1296.     while( pb->ioParam.ioResult > 0 )
  1297.         TaskYield();
  1298.  
  1299.     return pb->ioParam.ioResult;
  1300. }
  1301.  
  1302. static OSErr SetIndString( ConstStr255Param s, StringListHandle strList,
  1303. short i )
  1304. {
  1305.     short                k;
  1306.     Size                offset;
  1307.     StringPtr            p;
  1308.  
  1309.  
  1310.     if( i <= 0 )
  1311.         return paramErr;
  1312.  
  1313.     /* Add strings if necessary */
  1314.     k = i - ( *strList )->numStrings;
  1315.     if( k > 0 ) {
  1316.         OSErr            err;
  1317.         short            j;
  1318.  
  1319.  
  1320.         /* Add enough length bytes to the end of the string list */
  1321.         offset = GetHandleSize(( Handle )strList );
  1322.         SetHandleSize(( Handle )strList, offset + k );
  1323.         err = MemError();
  1324.         if( err != noErr )
  1325.             return err;
  1326.  
  1327.         /* Initialize length bytes to 0 */
  1328.         p = ( StringPtr )*strList + offset;
  1329.         for( j = 0; j < k; j++ )
  1330.             *p++ = 0;
  1331.  
  1332.         ( *strList )->numStrings = i;
  1333.     }
  1334.  
  1335.     /* Determine the offset to the requested string */
  1336.     offset = sizeof( short );
  1337.     p = ( *strList )->string;
  1338.     for( k = 1; k < i; k++ ) {
  1339.         Size            length;
  1340.  
  1341.  
  1342.         length = p[ 0 ] + 1;
  1343.         offset += length;
  1344.         p += length;
  1345.     }
  1346.  
  1347.     /* Replace the string */
  1348.     Munger(( Handle )strList, offset, 0, p[ 0 ] + 1, ( Ptr )s, s[ 0 ] + 1 );
  1349.     return MemError();
  1350. }
  1351.  
  1352. static OSErr ReadField( ImportHandle ctx, StringPtr field, Boolean
  1353. *endOfRecord )
  1354. {
  1355.     OSErr                err;
  1356.     Ptr                    buffer;
  1357.     short                length;
  1358.     char                c;
  1359.  
  1360.  
  1361.     buffer = ( *ctx )->pb->ioParam.ioBuffer + ( *ctx )->bufIndex;
  1362.     length = 0;
  1363.     *endOfRecord = FALSE;
  1364.     err = noErr;
  1365.  
  1366.     for( ;; ) {
  1367.         /* If the buffer is depleted, read some more in */
  1368.         if(( *ctx )->bufIndex >= ( *ctx )->pb->ioParam.ioActCount ) {
  1369.  
  1370.             /* If we've already reached the end of file, break out */
  1371.             if(( *ctx )->endOfFile ) {
  1372.                 err = eofErr;
  1373.                 *endOfRecord = TRUE;
  1374.                 break;
  1375.             }
  1376.  
  1377.             /* Read the next buffer full */
  1378.             err = TRead(( *ctx )->pb );
  1379.             if( err != noErr ) {
  1380.  
  1381.                 /* Remember if we hit end of file, and keep going */
  1382.                 if( err == eofErr ) {
  1383.                     err = noErr;
  1384.                     ( *ctx )->endOfFile = TRUE;
  1385.                 }
  1386.  
  1387.                 /* Break out if any other read errors */
  1388.                 else
  1389.                     break;
  1390.             }
  1391.     
  1392.             /* Reset index into buffer */
  1393.             ( *ctx )->bufIndex = 0;
  1394.             buffer = ( *ctx )->pb->ioParam.ioBuffer;
  1395.         }
  1396.  
  1397.         /* Retrieve next character from buffer */
  1398.         c = *buffer++;
  1399.         ( *ctx )->bufIndex++;
  1400.  
  1401.         /* End of field? */
  1402.         if( c == '\t' )
  1403.             break;
  1404.  
  1405.         /* End of record? */
  1406.         if( c == '\r' ) {
  1407.             *endOfRecord = TRUE;
  1408.             break;
  1409.         }
  1410.  
  1411.         /* Length exceeded? */
  1412.         if( length == sizeof( field ) - 1 )
  1413.             continue;
  1414.  
  1415.         /* Transfer to field */
  1416.         field[ ++length ] = c;
  1417.     }
  1418.  
  1419.     /* Set string length */
  1420.     field[ 0 ] = length;
  1421.     return err;
  1422. }
  1423.  
  1424. static OSErr ReadHeader( ImportHandle ctx, short columnListID )
  1425. {
  1426.     OSErr                err;
  1427.     StringListHandle    columnList;
  1428.     short                i, nReqColumns, col;
  1429.     short                **columnMap;
  1430.     Str255                columnName, findName;
  1431.     Boolean                endOfRecord, found;
  1432.  
  1433.  
  1434.     /* Retrieve the string list */
  1435.     columnList = ( StringListHandle )GetResource( 'STR#', columnListID );
  1436.     if( !columnList ) {
  1437.         err = ResError();
  1438.         if( err == noErr )
  1439.             err = resNotFound;
  1440.         return err;
  1441.     }
  1442.  
  1443.     /* Retrieve number of columns */
  1444.     nReqColumns = ( *columnList )->numStrings;
  1445.     ( *ctx )->nReqColumns = nReqColumns;
  1446.  
  1447.     /* Allocate column map */
  1448.     columnMap = ( short ** )NewHandle( 0 );
  1449.     if( !columnMap )
  1450.         return MemError();
  1451.     ( *ctx )->columnMap = columnMap;
  1452.  
  1453.     /* Read labels from first record */
  1454.     for( col = 1;; col++ ) {
  1455.  
  1456.         /* Let other tasks run */
  1457.         TaskYield();
  1458.  
  1459.         /* Read a field */
  1460.         err = ReadField( ctx, columnName, &endOfRecord );
  1461.         if( err != noErr )
  1462.             break;
  1463.  
  1464.         /* Map labels to column names */
  1465.         found = FALSE;
  1466.         for( i = 1; i <= nReqColumns; i++ ) {
  1467.             GetIndString( findName, columnListID, i );
  1468.             if( EqualString( columnName, findName, FALSE, FALSE )) {
  1469.                 found = TRUE;
  1470.                 break;
  1471.             }
  1472.         }
  1473.  
  1474.         /* If not found, then this column will be ignored */
  1475.         if( !found )
  1476.             i = 0;
  1477.  
  1478.         /* Append to column map */
  1479.         err = PtrAndHand(( Ptr )&i, ( Handle )columnMap, sizeof( i ));
  1480.         if( err != noErr )
  1481.             break;
  1482.  
  1483.         if( endOfRecord )
  1484.             break;
  1485.     }
  1486.  
  1487.     if( err == eofErr )
  1488.         err = noErr;
  1489.     return err;
  1490. }
  1491.  
  1492. static OSErr ReadData( ImportHandle ctx, RowActionProc rowAction, long
  1493. refCon )
  1494. {
  1495.     OSErr                err;
  1496.     short                col, nReqColumns, nColumns;
  1497.     StringPtr            p;
  1498.     short                **columnMap, i;
  1499.     StringListHandle    rowData;
  1500.     Boolean                endOfRecord;
  1501.     Str255                field;
  1502.  
  1503.  
  1504.     columnMap = ( *ctx )->columnMap;
  1505.     nColumns = GetHandleSize(( Handle )columnMap )/sizeof( short );
  1506.  
  1507.     /* Allocate rowData string list */
  1508.     nReqColumns = ( *ctx )->nReqColumns;
  1509.     rowData = ( StringListHandle )NewHandle( sizeof( short ) + nReqColumns );
  1510.     if( !rowData )
  1511.         return MemError();
  1512.     ( *ctx )->rowData = rowData;
  1513.  
  1514.     /* Read rows until an error occurs */
  1515.     for( ;; ) {
  1516.  
  1517.         /* Initialize row data to nReqColumns empty strings */
  1518.         ( *rowData )->numStrings = nReqColumns;
  1519.         p = ( *rowData )->string;
  1520.         for( i = 0; i < nReqColumns; i++ ) {
  1521.             *p++ = 0;
  1522.         }
  1523.  
  1524.         /* Read a row */
  1525.         for( col = 0, endOfRecord = FALSE; !endOfRecord; col++ ) {
  1526.  
  1527.             /* Let other tasks run */
  1528.             TaskYield();
  1529.     
  1530.             /* Read a field */
  1531.             err = ReadField( ctx, field, &endOfRecord );
  1532.             if( err != noErr )
  1533.                 break;
  1534.  
  1535.             /* Skip excess unlabeled columns */
  1536.             if( col >= nColumns )
  1537.                 continue;
  1538.  
  1539.             /* Get column index; skip unrecognized columns */
  1540.             i = ( *columnMap )[ col ];
  1541.             if( i == 0 )
  1542.                 continue;
  1543.  
  1544.             /* Insert this field into the row data */
  1545.             err = SetIndString( field, rowData, i );
  1546.             if( err != noErr )
  1547.                 break;
  1548.         }
  1549.  
  1550.         /* Get out now if errors occurred */
  1551.         if( err != noErr )
  1552.             break;
  1553.  
  1554.         /* Call row action proc */
  1555.         err = ( *rowAction )( rowData, refCon );
  1556.         if( err != noErr )
  1557.             break;
  1558.  
  1559.         /* Reset row data for next row */
  1560.         SetHandleSize(( Handle )rowData, sizeof( short ) + nReqColumns );
  1561.     }
  1562.  
  1563.     if( err == eofErr )
  1564.         err = noErr;
  1565.     return err;
  1566. }
  1567.  
  1568. OSErr Import( FSSpecPtr file, short columnListID,
  1569.                 RowActionProc rowAction, long refCon )
  1570. {
  1571.     OSErr                err;
  1572.     ImportHandle        ctx;
  1573.     short                exitLevel;
  1574.     HParmBlkPtr            pb;
  1575.     Ptr                    buffer;
  1576.  
  1577.  
  1578.     /* Allocate import context info */
  1579.     ctx = ( ImportHandle )NewHandle( sizeof( ImportRecord ));
  1580.     if( !ctx )
  1581.         return MemError();
  1582.  
  1583. #if TASK
  1584.     /* Install exit routine */
  1585.     err = AtTaskExit(( TaskProcPtr )ImportExit, ( long )ctx, &exitLevel );
  1586.     if( err != noErr ) {
  1587.         DisposHandle(( Handle )ctx );
  1588.         return err;
  1589.     }
  1590. #endif
  1591.  
  1592.     /* Initialize context info */
  1593.     ( *ctx )->pb = 0;
  1594.     ( *ctx )->bufIndex = 0;
  1595.     ( *ctx )->endOfFile = FALSE;
  1596.     ( *ctx )->columnMap = 0;
  1597.     ( *ctx )->rowData = 0;
  1598.  
  1599.     /* Allocate the parameter block */
  1600.     pb = ( HParmBlkPtr )NewPtr( sizeof( HParamBlockRec ));
  1601.     if( !pb ) {
  1602.         err = MemError();
  1603.         goto errExit;
  1604.     }
  1605.     ( *ctx )->pb = pb;
  1606.  
  1607.     /* Fill out parameter block for open */
  1608.     pb->ioParam.ioRefNum = 0;
  1609.     pb->ioParam.ioBuffer = 0;
  1610.     pb->ioParam.ioVRefNum = file->vRefNum;
  1611.     pb->fileParam.ioDirID = file->parID;
  1612.     pb->ioParam.ioNamePtr = file->name;
  1613.     pb->ioParam.ioVersNum = 0;
  1614.     pb->ioParam.ioPermssn = fsRdPerm;
  1615.     pb->ioParam.ioMisc = 0;
  1616.  
  1617.     /* Open the import file */
  1618.     err = TOpen( pb );
  1619.     if( err != noErr )
  1620.         goto errExit;
  1621.  
  1622.     /* Allocate the input buffer */
  1623.     buffer = NewPtr( kImportBufferSize );
  1624.     if( !buffer ) {
  1625.         err = MemError();
  1626.         goto errExit;
  1627.     }
  1628.  
  1629.     /* Set up parameter block for reading */
  1630.     pb->ioParam.ioBuffer = buffer;
  1631.     pb->ioParam.ioReqCount = kImportBufferSize;
  1632.     pb->ioParam.ioActCount = 0;
  1633.     pb->ioParam.ioPosMode = fsAtMark;
  1634.     pb->ioParam.ioPosOffset = 0;
  1635.  
  1636.     /* Read the header */
  1637.     err = ReadHeader( ctx, columnListID );
  1638.     if( err != noErr )
  1639.         goto errExit;
  1640.  
  1641.     /* Read the data */
  1642.     err = ReadData( ctx, rowAction, refCon );
  1643.  
  1644. errExit:
  1645. #if TASK
  1646.     TaskExit( exitLevel );
  1647. #else
  1648.     ImportExit( ctx );
  1649. #endif
  1650.     return err;
  1651. }
  1652.  
  1653. =======================================================================
  1654.  
  1655. /* This example shows how you would create a task that calls Import */
  1656.  
  1657. #include "Task.h"
  1658.  
  1659. #define kColumnLabels    131
  1660.  
  1661.  
  1662. static OSErr ImportRow( StringListHandle rowData, long refCon )
  1663. {
  1664.     /* Process the row data here */
  1665.  
  1666.     /* Return an error code (ie: userCanceledErr) to stop */
  1667.     return noErr;
  1668. }
  1669.  
  1670. static void ImportTask( FSSpecPtr file )
  1671. {
  1672.     UnexpectedError( Import( file, kColumnLabels, ImportRow, 0 ));
  1673. }
  1674.  
  1675. OSErr NewImportTask( FSSpecPtr file )
  1676. {
  1677.     /* Spawn a task to import the text file */
  1678.     return NewTask(( TaskProcPtr )ImportTask, ( long )file, 0 );
  1679. }
  1680.  
  1681. ---------------------------
  1682.  
  1683. End of C.S.M.P. Digest
  1684. **********************
  1685.